import bcrypt from 'bcryptjs';
import { pool } from '../config/database';
import { AppError } from '../middlewares/errorHandler';

export class PasswordService {
  private static instance: PasswordService;
  private readonly SALT_ROUNDS = 10;

  private constructor() {}

  public static getInstance(): PasswordService {
    if (!PasswordService.instance) {
      PasswordService.instance = new PasswordService();
    }
    return PasswordService.instance;
  }

  // 加密密码
  async hashPassword(password: string): Promise<string> {
    return bcrypt.hash(password, this.SALT_ROUNDS);
  }

  // 验证密码
  async verifyPassword(password: string, hash: string): Promise<boolean> {
    return bcrypt.compare(password, hash);
  }

  // 修改密码
  async changePassword(userId: string, oldPassword: string, newPassword: string) {
    const connection = await pool.getConnection();
    try {
      await connection.beginTransaction();

      // 获取用户当前密码
      const [rows] = await connection.query(
        'SELECT password FROM users WHERE id = ?',
        [userId]
      );

      if (!rows[0]) {
        throw new AppError('用户不存在', 404);
      }

      // 验证旧密码
      const isValid = await this.verifyPassword(oldPassword, rows[0].password);
      if (!isValid) {
        throw new AppError('旧密码错误', 400);
      }

      // 加密新密码
      const hashedPassword = await this.hashPassword(newPassword);

      // 更新密码
      await connection.query(
        'UPDATE users SET password = ? WHERE id = ?',
        [hashedPassword, userId]
      );

      await connection.commit();
      return true;
    } catch (error) {
      await connection.rollback();
      throw error;
    } finally {
      connection.release();
    }
  }

  // 重置密码
  async resetPassword(userId: string, newPassword: string) {
    try {
      const hashedPassword = await this.hashPassword(newPassword);
      await pool.query(
        'UPDATE users SET password = ? WHERE id = ?',
        [hashedPassword, userId]
      );
      return true;
    } catch (error) {
      throw new AppError('重置密码失败', 500);
    }
  }

  // 初始化管理员密码
  async initAdminPassword() {
    try {
      const hashedPassword = await this.hashPassword('admin');
      await pool.query(
        'UPDATE users SET password = ? WHERE username = ?',
        [hashedPassword, 'admin']
      );
      return true;
    } catch (error) {
      throw new AppError('初始化管理员密码失败', 500);
    }
  }
} 